package cn.yunhe.Aop;

import cn.yunhe.dao.SysLogDao;
import cn.yunhe.entity.SysLog;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;

@Aspect
@Component
public class Advice {
    @Autowired
    private SysLogDao sysLogDao;
    //环绕通知
    @Around("myPointCut()")
    public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        //获取securityContext的上下文对象
        SecurityContext context = SecurityContextHolder.getContext();
        //获取认证信息
        Authentication authentication = context.getAuthentication();
        if (authentication != null) {
            //登陆了
            Logger logger = LoggerFactory.getLogger(Advice.class);
            //获取时间日期
            Date date = new Date();
            //获取目标类
            Class<?> aClass = proceedingJoinPoint.getTarget().getClass();
            //获取正在执行的方法
            String methodName = proceedingJoinPoint.getSignature().getName();
            if ("findAll".equals(methodName)){
                return proceedingJoinPoint.proceed();
            }
            //正在执行方法的参数
            Object[] args = proceedingJoinPoint.getArgs();
            //打印获取的内容
            logger.info("======>" + date.toLocaleString() + "执行了" + aClass + "的" + methodName + "方法的参数" + Arrays.toString(args));
            //执行目标方法
            Object proceed = proceedingJoinPoint.proceed();
            SysLog sysLog = new SysLog();
            String methodStr="[类名]\t"+aClass+"[方法名]\t"+methodName;
            sysLog.setMethod(methodStr);
            //获取用户对象
            User user = (User) authentication.getPrincipal();
            sysLog.setUsername(user.getUsername());
            sysLog.setVisitTime(new Date(date.getTime()));
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            //获取请求对象
            HttpServletRequest request = requestAttributes.getRequest();
            //获取请求路径
            sysLog.setUrl(request.getRequestURI().toString());
            sysLog.setIp(request.getRemoteAddr());
            //获取当前系统的名字
            long l = System.currentTimeMillis();
            sysLog.setExecutionTime(l- date.getTime());
            sysLogDao.saveSysLog(sysLog);
            return proceed;
        }else {
            //不添加日志只执行方法
            return  proceedingJoinPoint.proceed();
        }

    }
    /**
     * 增强Controller中的所有方法
     * **/
    @Pointcut("execution(* cn.yunhe.controller.*.*(..))&&!execution(* cn.yunhe.controller.CountPage.*(..))")
    public void myPointCut() {
    }
}
